package Figures;

import Tools.Serializer;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.Serializable;


/**
 * 类功能描述：图形类的基类，声明了图形的属性和方法。
 *
 * @author lix
 * @date 2023/12/28 21:03
 */

public abstract class Figure implements Serializable {

    public void setSelected(boolean selected) {
        isSelected = selected;
    }

    protected boolean isSelected;
    //图形矩形边框左上角的点
    protected Point point_left_top;
    //图形中心点
    protected Point point_center;
    //图形矩形边框右下角点
    protected Point point_right_bottom;

    //起点和终点属性，颜色，大小等
    protected int size;

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    protected Point start;

    public Point getStart() {
        return start;
    }

    public void setStart(Point start) {
        this.start = start;
    }

    protected Point end;

    public Point getEnd() {
        return end;
    }

    public void setEnd(Point end) {
        this.end = end;
    }

    protected Color ShapeColor;

    protected int width;
    protected int height;

    public Color getShapeColor() {
        return ShapeColor;
    }

    /**
     * 功能描述：
     * 设置图形的画笔的颜色(shapeColor)
     *
     * @param shapeColor 图形的画笔颜色
     * @author lix
     * @date 2023/12/28 21:55
     */

    public void setShapeColor(Color shapeColor) {
        ShapeColor = shapeColor;
    }


    /**
     * 功能描述：
     * 图形的绘制方法。
     *
     * @param g 绘制图形的Graphics2D类
     * @author lix
     * @date 2023/12/28 21:21
     */
    public abstract void Draw(Graphics2D g);

    /**
     * 功能描述：
     * 图形的中心点移动到坐标(destination)，来实现图形在画板中的移动
     * @param destination 移动到目标点
     * @author lix
     * @date 2023/12/28 21:14
     */
    public void Move(Point destination){
        Point old_center = this.point_center;
        this.point_center= destination;
        //更新起点和终点
        Point new_start = new Point((this.start.x+(destination.x-old_center.x)),(this.start.y+(destination.y-old_center.y)));
        Point new_end   = new Point((this.end.x+(destination.x-old_center.x)),(this.end.y+(destination.y-old_center.y)));
        start = new_start;
        end = new_end;
        //更新左上角和右下角点
        calcPoint_left_top();
        calcPoint_right_bottom();
    }


    /**
     * 功能描述：
     *缩放图形
     * @param end 拉伸图像后的终点位置大小
     * @author lix
     * @date 2023/12/30
     */

    public void Stretch(Point end){
        setEnd(end);
        calcPoint_left_top();
        calcPoint_right_bottom();
        calcWidthAndHeight();
        point_center = new Point(((point_left_top.x+point_right_bottom.x)/2),(point_left_top.y+point_right_bottom.y)/2);

    }



    public Figure(Point start, Point end, int size, Color color) {
        this.start = start;
        this.end = end;
        //设置左上角坐标和右下角坐标
        calcPoint_left_top();
        calcPoint_right_bottom();
        //设置高度和宽度
        calcWidthAndHeight();
        //设置大小
        this.size = size;
        //设置颜色
        this.ShapeColor = color;
    }

    protected void calcPoint_left_top() {
        point_left_top = new Point(Math.min(start.x, end.x), Math.min(start.y, end.y));
    }

    protected void calcPoint_right_bottom() {
        point_right_bottom = new Point(Math.max(start.x, end.x), Math.max(start.y, end.y));
    }

    protected void calcWidthAndHeight() {
        width = point_right_bottom.x - point_left_top.x;
        height = point_right_bottom.y - point_left_top.y;
    }

    /**
     * 功能描述：
     * 判断鼠标是否在图形矩形框的内部
     *
     * @param e 鼠标坐标
     * @return boolean
     * @author lix
     * @date 2023/12/30
     */

    public boolean contains(MouseEvent e) {
        Rectangle boundingBox = new Rectangle(point_left_top.x, point_left_top.y, width, height);
        return boundingBox.contains(e.getPoint());
    }

    /**
     * 功能描述：
     *显示被选中图形的虚线边框
     * @param g Graphics2D对象
     * @author lix
     * @date 2023/12/30
     */

    protected void showSelectBorder(Graphics2D g){
            g.setColor(Color.black);
            g.setStroke(new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{5}, 0));
            g.drawRect(point_left_top.x-size,point_left_top.y-size , Math.abs(start.x - end.x)+size*2, Math.abs(start.y - end.y)+size*2);

    }



}
